package matrice;


public class EvalMask {

	private Boolean[][] matrice;
	private int taille;
	
	public void setMatrice(Boolean[][] matrice) {
		this.matrice = matrice;
		this.taille = this.matrice.length;
	}
	
	public int eval() {
		int score1 = evalRule1();
		int score2 = evalRule2();
		int score3 = evalRule3();
		int score4 = evalRule4();
	//	System.out.println("\n1: "+score1+"\n 2: "+score2+"\n 3 :"+ score3+"\n 4: "+score4);
		return score1 + score2 + score3 + score4;
	}
	
	// Règle 1 : 5 pixels ou plus  de la même couleur alignés
	private int evalRule1() {
		int scoreHoriz = 0;
		int scoreVerti = 0;

		// Alignement horizontal
		for(int i=0; i<taille; i++) {
			for(int j=0; j<taille; j++) {
				int c = 1;
				
				while(j+c < taille && matrice[i][j] == matrice[i][j+c])	
					c++;
				
				j += c-1;
				
				if(c >= 5) {
					c = 3 + (c - 5);
					scoreHoriz += c;
				}
			}
		}

		// Alignement vertical
		for(int col=0; col<taille; col++) {
			for(int l=0; l<taille; l++) {
				int c = 1;
				
				while(l+c < taille && matrice[l][col] == matrice[l+c][col])
					c++;
				
				l += c-1;
				
				if(c >= 5) {
					c = 3 + (c - 5);
					scoreVerti += c;
				}
			}
		}
		
		return scoreHoriz+scoreVerti;
	}
	
	// Règle 2 : Groupe de 2x2 pixels
	private int evalRule2() {
		int score = 0;
		
		for(int i=0; i<taille-1; i++) {
			for(int j=0; j<taille-1; j++) {
				if(this.matrice[i][j] == this.matrice[i+1][j]
				   && this.matrice[i][j] == this.matrice[i][j+1]
				   && this.matrice[i][j] == this.matrice[i+1][j+1]) {
					score += 3;
				}
			}
		}
		
		return score;
	}
	
	
	// Règle 3 : Alignements qui ressemblent aux detections positions patterns
	private int evalRule3() {
		int score = 0;

		boolean[][] alignPatterns = {{true,false,true,true,true,false,true,false,false,false,false},
								   {false,false,false,false,true,false,true,true,true,false,true},
								   {false,false,false,false,true,false,true,true,true,false,true,false,false,false,false}};

		for(int i=0; i<this.taille; i++) {
			for(int j=0; j<this.taille; j++) {
				for(int k=0; k<alignPatterns.length; k++) {
					
					if(alignement('L', alignPatterns[k], i, j))
						score += 40;
					
					if(alignement('C', alignPatterns[k], i, j))
						score += 40;
				}
			}
		}
		
		return score;
	}
	
	/**
	 * Vérifie si une suite de modules correspond à un alignement pattern
	 * @param axe
	 * @param alignPattern
	 * @param line
	 * @param col
	 * @return
	 */
	private boolean alignement(char axe, boolean[] alignPattern, int line, int col) {
		if((line > matrice.length-alignPattern.length && axe == 'C') ||
			(col > matrice.length-alignPattern.length && axe == 'L'))
			return false;
		
		boolean align = true;

		for(int k=0; k<alignPattern.length; k++) {

			if(axe == 'L') {
				int colMat = col + k;
				if(matrice[line][colMat] != alignPattern[k])
					align = false;
			}
			else if(axe == 'C') {
				int lineMat = line + k;
				if(matrice[lineMat][col] != alignPattern[k])
					align = false;
			}
		}
		
		return align;
	}
	
	// Règle 4 : Ratio entre le nombre de pixels blancs et le nombre de pixels noirs
	private int evalRule4() {
		int score = 0;
		float tmpScore = 0;
		int blackPixel = 0;
		float ratio = 0;
		
		for(int i=0; i<taille; i++) {
			for(int j=0; j<taille; j++) {
				if(this.matrice[i][j] == true) {
					blackPixel++;
				}
			}
		}
		
		ratio = (float) blackPixel / (taille*taille);
		tmpScore = ratio * 100 - 50;
		if(tmpScore < 0)
			tmpScore = -tmpScore;
		
		float absoluteTmp = (int) tmpScore;
			tmpScore = (absoluteTmp / 5) * 10;

		score = (int) tmpScore;

		return score;
	}
}
